{
	"translatorID": "74233d17-473f-45bf-95ce-3ef9c54048be",
	"label": "Douban2",
	"creator": "Huchian <Huchian@foxmail.com>",
	"target": "^https?://((search\\.douban\\.com/book/subject_search)|(book\\.douban\\.com/subject/)).*",
	"minVersion": "0.1",
	"maxVersion": "",
	"priority": 99,
	"inRepository": true,
	"translatorType": 12,
	"browserSupport": "gcsibv",
	"lastUpdated": "2023-07-02 11:59:10"
}

/**
 * 源自Douban.js，做了一些优化调整，便于阅读理解和后续修改
 */


function detectWeb(doc, url) {
	
	// Z.debug(url)

	//目前此pattern兼容搜索、豆列、人物等含有图书列表的页面
	var pattern = /subject_search|doulist|people\/[a-zA-Z._]*?\/(?:do|wish|collect)|.*?status=(?:do|wish|collect)|group\/[0-9]*?\/collection|tag/;
	if (pattern.test(url)) {
		return "multiple";
	}
	//search url eg.
	//https://search.douban.com/book/subject_search?search_text=Classics%3A+An+Investor%27s+Anthology&cat=1001

	//book url eg. https://book.douban.com/subject/19896414/
	pattern = /book\.douban\.com\/subject/;
	if (pattern.test(url)) {
		return "book";
	}

	return false;
	
}

function detectTitles(doc, url) {
	var pattern = /\.douban\.com\/tag\//;
	if (pattern.test(url)) {
		return ZU.xpath(doc, '//div[@class="info"]/h2/a');
	} else {
		return ZU.xpath(doc, '//div[@class="title"]/a');
	}
}

function doWeb(doc, url) {
	var articles = [];
	let r = /douban.com\/url\//;
	let webType = detectWeb(doc, url);

	if (webType == "multiple") {
		// also searches but they don't work as test cases in Scaffold
		// e.g. https://book.douban.com/subject_search?search_text=Murakami&cat=1001
		var items = {};
		// var titles = ZU.xpath(doc, '//div[@class="title"]/a');
		var titles = detectTitles(doc, url);
		var title;
		for (let i = 0; i < titles.length; i++) {
			title = titles[i];
			// Zotero.debug({ href: title.href, title: title.textContent });
			if (r.test(title.href)) { // Ignore links
				continue;
			}
			items[title.href] = title.textContent;
		}
		// Z.debug(items)

		Zotero.selectItems(items, function (items) {
			if (!items) {
				return;
			}
			for (var i in items) {
				articles.push(i);
			}

			ZU.processDocuments(articles, scrapeAndParse);
		});
	}

	//book页
	if(webType == 'book'){
		parseBookPage(doc, url)
	}
	
	//TODO::考虑异常
}

function trimTags(text) {
	return text.replace(/(<.*?>)/g, "");
}

// #############################
// ##### Scraper functions #####
// #############################
function scrapeAndParse(doc, url) {
	
	ZU.doGet(url, function (page) {
		let bookDom = new DOMParser().parseFromString(page, 'text/html');
		parseBookPage(bookDom, url);
	});
}

/**
 * 解析 book 页面
 */
function parseBookPage(doc, url){
	let page = doc.body.innerHTML
	
	var pattern, extra;
	var info = {}	//保存解析出的额外信息

	// 类型 & URL
	var newItem = new Zotero.Item("book");
	newItem.url = url;

	//处理 id="info" 的 div 包含各种基本信息
	parseBookInfoBlock(doc, newItem, info)
	// Z.debug(info)

	// 标题
	pattern = /<h1>([\s\S]*?)<\/h1>/;
	if (pattern.test(page)) {
		var title = pattern.exec(page)[1];
		title = ZU.trim(trimTags(title))
		
		// 判断下副标题与标题一样否,避免重复
		newItem.title = title;
		concatStr = ": " //连接字符默认半角，如有汉字改为全角
		if (/[\u4E00-\u9FA5\uFE30-\uFFA0]/.test(title)) { concatStr = "："	} 
		if((title !== info.subTitle) & (info.subTitle.length > 0)){ 
			newItem.title = title + concatStr + info.subTitle;
		}
		// 短标题
		newItem.shortTitle = title
	}
	
	// 评分
	let dbScore = ZU.xpathText(doc, '//*[@id="interest_sectl"]/div[1]/div[2]/strong')
	dbScoreNum = Number(dbScore.trim())
	if(dbScoreNum){
		dbScore = Math.round(dbScoreNum) + "⭐"
		newItem.tags.push(dbScore);
	}
	
	// 评价人数
	let commentNum = ZU.xpathText(doc, '//*[@id="interest_sectl"]/div[1]/div[2]/div/div[2]/span/a/span')

	// 目录
	let catalogueList = ZU.xpath(doc, "//div[@class='indent' and contains(@id, 'dir_') and contains(@id, 'full')]")
	let catalogue = ""
	if(catalogueList.length>0){
		catalogue = catalogueList[0].innerHTML.replace(/· · · · · ·.*?\n/g,"")
		catalogue = "<h1>#摘录-《"+title+"》目录</h1>\n" + catalogue
		newItem.notes.push({note:catalogue})
	}
			
	//补全0
	function completeDate(value) {
		return value < 10 ? "0"+value:value;
	}

	// 标签
	var tags = ZU.xpath(doc, '//div[@id="db-tags-section"]/div[@class="indent"]/span/a[contains(@class, "tag") ]');
	for (let i in tags) {
		newItem.tags.push(tags[i].text);
	}
	
	// 作者简介
	let authorInfoList = ZU.xpath(doc, "//span[text()='作者简介']/parent::h2/following-sibling::div//div[@class='intro']")
	// 这里会获取平级的元素,当有多个时(有展开全部按钮)取最后一个
	let authorInfo = ""
	let authorInfotwo = ""
	if(authorInfoList.length>0){
		authorInfo = authorInfoList[authorInfoList.length-1].innerHTML
		// 正则提取<p>标签里面的元素,并添加换行 TODO:: 更好的处理文本格式转换 避免  authorInfo 异常
		authorInfo = authorInfo.match(/<[a-zA-Z]+.*?>([\s\S]*?)<\/[a-zA-Z]+.*?>/g)
		if (authorInfo){
			for(i=0;i<authorInfo.length;i++){
				authorInfo[i] = authorInfo[i].match(/<[a-zA-Z]+.*?>([\s\S]*?)<\/[a-zA-Z]+.*?>/g)
				authorInfotwo = authorInfotwo+RegExp.$1+"\n"
			}
			newItem.notes.push({note:"作者简介:"+"\n"+authorInfotwo+"\n"})
		}
	}

	// 内容简介
	// 获取展开全部按钮里面的内容
	let contentInfoList = ZU.xpath(doc, "//span[text()='内容简介']/parent::h2/following-sibling::div[@id='link-report']//div[@class='intro']")
	let contentInfo = ""
	let contentInfoTwo = ""
	if(contentInfoList.length>0){
		// TODO:: 更好的处理文本格式转换 避免  contentInfo 异常
		contentInfo = contentInfoList[contentInfoList.length-1].innerHTML
		contentInfo = contentInfo.match(/<[a-zA-Z]+.*?>([\s\S]*?)<\/[a-zA-Z]+.*?>/g)
		if(contentInfo){
			for(i=0;i<contentInfo.length;i++){
				contentInfo[i] = contentInfo[i].match(/<[a-zA-Z]+.*?>([\s\S]*?)<\/[a-zA-Z]+.*?>/g)
				contentInfoTwo = contentInfoTwo+RegExp.$1+"\n"
			}
			newItem.abstractNote = "内容简介:"+"\n"+contentInfoTwo
		}
	}
	

	// 其他
	extra = "评价人数：" + commentNum+"；"
	// extra += "分："+ dbScore + "；"
	if(info.originalTitle){ // 当没有原名时,使用空字符
		extra += "原作名：《" + info.originalTitle + "》；"
	}
	//TODO::优化容错
	extra = extra.replace(/( - )?undefined/g,"").replace("null","0")
	//价格
	let price = ''
	//Z.debug(info.priceUnit)
	if('priceUnit' in info){
		if(info.priceUnit==="" || info.priceUnit.includes("CNY")){
			price = info.priceNum + " 元";
		} else {
			price = info.priceUnit + info.priceNum;
		}
		extra += "价：" + price + ';';
	}
	newItem.extra = extra
	

	newItem.complete();
}

/**
 * 处理 id="info" 的 div，包含主要信息
 */
function parseBookInfoBlock(doc, newItem, info){
	var infoBlock = ZU.xpath(doc, '//div[@id="info"]')[0].innerHTML
	infoBlock = infoBlock.replace(/\n/g, "").replace(/\s{2,}/g," ");
	
	// TODO::优化 parse 
	// Z.debug(infoBlock.replace(/<br\/?>/g,"\n").split('\n'))
	page = infoBlock

	// 作者
	page = page.replace(/\n/g, "");
	page = page.replace(/&nbsp;/g,"")
	// Z.debug(page)
	// 豆瓣里作者一栏及其不规范,这里使用多正则匹配更多情况,提高兼容性
	let regexp = new RegExp() // 这里要把类型定义为RegExp,否则下面赋值后test(page)会失败
	let regexp2 = new RegExp()
	let regexp3 = new RegExp()
	regexp = /<span>\s*<span[^>]*?>\s*作者<\/span>:(.*?)<\/span>/;
	regexp2 = /<span class="pl">作者:<\/span>\s*?<a href="https:\/\/book\.douban\.com\/author\/\d+\/">\s*?\S*?\s*?\S*?<\/a>\s*?<br>/
	regexp3 = /<span class="pl">作者:<\/span>\s*?<a href="https:\/\/book\.douban\.com\/author\/\d+\/">\s*?\S*?\s*?\S*?<\/a>\s+\//
	if (regexp2.test(page)) { 
		regexp = regexp2
	} else if(regexp3.test(page)){
		regexp = regexp3
	}
	
	if (regexp.test(page)) { 
		var authorNames = trimTags(regexp.exec(page)[0]);
		pattern = /(\[.*?\]|\(.*?\)|（.*?）)/g;
		authorNames = authorNames.replace(pattern, "").split("/");
		// 国家
		let country = RegExp.$1
		country = country.replace("美国","美")
		country = country.match(/[一-龥]+/g)
		if(country===null){
			country = [" "]
		}

		// Zotero.debug(authorNames);
		let firstNameList = [] // 作者名列表
		let lastNameList = [] // 作者姓列表
		info.creators = []
		for (let i = 0; i < authorNames.length; i++) {
			let useComma = true;
			pattern = /[A-Za-z]/;
			if (pattern.test(authorNames[i])) {
			// 外文名
				pattern = /,/;
				if (!pattern.test(authorNames[i])) {
					useComma = false;
				}
			}
			// 实现欧美作者姓与名分开展示
			let patt1 = new RegExp("·.+\.+")
			let authorNameTemp = ""
			let ming = ""
			let xing = ""
			
			authorNames[i] = authorNames[i].replace(/作者:?(&nbsp;)?\s+/g, "")
			if(authorNames[i].indexOf(".")!= -1){ // 名字中带.的   如:斯蒂芬·D.埃平格
				authorNameTemp = authorNames[i].trim().split(".")
				xing = authorNameTemp.pop() // 取数组最后一个值作为名
				ming = authorNameTemp.join("·") // 姓氏
			} else {
				authorNames[i] =authorNames[i].replace(/•/g,"·") // 替换中文•分隔符为英文·
				authorNameTemp = authorNames[i].trim().split("·")
				xing = authorNameTemp.pop()
				ming = authorNameTemp.join("·")
			}
			xing = xing.trim()
			ming = ming.trim()
			if(country[i]){
				country = country[i].replace(/<\/a>/g,"")
			}

			info.creators.push({
				firstName: ming,
				lastName: xing,
				country: country
			})
		
			firstNameList.push(ming)
			// if(country!=" "){
			// 	country = "["+country+"]"
			// 	firstNameList.push(country+ming)
			// }else{
				
			// }
			
			lastNameList.push(xing)
			
			newItem.creators.push({firstName:firstNameList[i],lastName:lastNameList[i], creatorType:"author", fieldMode:true});
			// newItem.creators.push(Zotero.Utilities.cleanAuthor(
			// 	Zotero.Utilities.trim(authorNames[i]),
			// 	"author", useComma));
		}
	}

	// 译者
	pattern = /<span>\s*<span [^>]*?>\s*译者<\/span>:(.*?)<\/span>/;
	if (pattern.test(page)) {
		var translatorNames = trimTags(pattern.exec(page)[1]);
		pattern = /(\[.*?\])/g;
		translatorNames = translatorNames.replace(pattern, "").split("/");
		//		Zotero.debug(translatorNames);
		for (let i = 0; i < translatorNames.length; i++) {
			let useComma = true;
			pattern = /[A-Za-z]/;
			if (pattern.test(translatorNames[i])) {
			// 外文名
				useComma = false;
			}
			newItem.creators.push(ZU.cleanAuthor(
				ZU.trim(translatorNames[i]),
				"translator", useComma));
		}
	}

	// 副标题
	info.subTitle = ''
	pattern = /<span [^>]*?>副标题:<\/span>(.*?)<br\/?>/;
	if (pattern.test(page)) {
		info.subTitle = pattern.exec(page)[1].trim()
	}

	// ISBN
	pattern = /<span [^>]*?>ISBN:<\/span>(.*?)<br\/?>/;
	if (pattern.test(page)) {
		var isbn = pattern.exec(page)[1];
		newItem.ISBN = ZU.trim(isbn);
		// Zotero.debug("isbn: "+isbn);
	}

	// 页数
	pattern = /<span [^>]*?>页数:<\/span>(.*?)<br\/?>/;
	if (pattern.test(page)) {
		var numPages = pattern.exec(page)[1];
		newItem.numPages = ZU.trim(numPages);
		// Zotero.debug("numPages: "+numPages);
	}

	// 出版社
	// Zotero.debug("page: "+page);
	pattern = /<span [^>]*?>出版社:<\/span>(.*?)<br\/?>/;
	if (pattern.test(page)) {
		var publisher = pattern.exec(page)[1];
		newItem.publisher = ZU.trim(trimTags(publisher));
		//Zotero.debug("publisher: "+publisher);
	}

	// 出版年
	pattern = /<span [^>]*?>出版年:<\/span>(.*?)<br\/?>/;
	if (pattern.test(page)) {
		var date = pattern.exec(page)[1];
		newItem.date = ZU.trim(date);
		// Zotero.debug("date: "+date);
	}

	// 定价
	pattern = /<span [^>]*?>定价:(.*?)<\/span>(.*?)<br\/?>/;
	var price;
	if (pattern.test(page)) {
		var price = pattern.exec(page)[2];
		// price = "60"
		let prefix = price.match(/^((?!(\d+\.?\d*)).)*/g)[0] // 正则匹配前缀,如USD,CAD
		price = price.match(/(\d+\.?\d*)/g)[0]
		
		// 小数点后2为保持
		let numPrice = Number(price) 
		numPrice = numPrice.toFixed(2)
		
		info.priceNum = numPrice
		info.priceUnit = prefix.trim()
	}

	// 原作名
	info.originalTitle = ""
	pattern = /<span [^>]*?>原作名:<\/span>(.*?)<br\/?>/;
	if (pattern.test(page)) {
		info.originalTitle = pattern.exec(page)[1].trim()
	}

	// 丛书
	pattern = /<span [^>]*?>丛书:<\/span>(.*?)<br\/?>/;
	if (pattern.test(page)) {
		var series = trimTags(pattern.exec(page)[0]);
		series = series.split("ISBN")[0].replace("丛书:", "");
		newItem.series = ZU.trim(series);
		// Zotero.debug("series: "+series);
	}

	// return newItem
}/** BEGIN TEST CASES **/
var testCases = [
	{
		"type": "web",
		"url": "https://search.douban.com/book/subject_search?search_text=Classics%3A+An+Investor%27s+Anthology&cat=1001",
		"items": "multiple"
	},
	{
		"type": "web",
		"url": "https://book.douban.com/subject/26427201/",
		"items": [
			{
				"itemType": "book",
				"title": "与巴菲特共进午餐时,我顿悟到的5个真理 - 探寻财富、智慧与价值投资的转变之旅",
				"creators": [
					{
						"firstName": "盖伊",
						"lastName": "斯皮尔",
						"creatorType": "author",
						"fieldMode": true
					},
					{
						"lastName": "张尧然",
						"creatorType": "translator"
					},
					{
						"lastName": "杨颖玥",
						"creatorType": "translator"
					}
				],
				"date": "2015-7-1",
				"ISBN": "9787515331515",
				"abstractNote": "内容简介:\n当一位年轻的对冲基金经理以65.01万美元竞拍价与巴菲特共进午餐将会发生什么？他成为了一名真正的价值投资者。\n《与巴菲特共进午餐时，我顿悟到的5个真理》记录了作者的重大转变，从一个年轻傲慢的投行经理，变成了一个坚守价值投资、取得高度成功的对冲基金经理人。作者的转变与进步，源于他的深刻反省、格雷厄姆与巴菲特的投资理念，同一些全球顶级投资家的学习与探讨，还有与心中偶像沃伦•巴菲特的一次午餐，这顿价值65.01美元的慈善午餐教给了他人生中最有价值的课程，包括非常规思维往往更好、永葆好奇心与童真、学会说不、忠实于自己、培养并维系有价值的人际关系。在这次午餐之后不到一年时间里，他从曼哈顿搬到了苏黎世，不再向新的投资者收取管理费，也不再上瘾着迷地查看股价。\n作者的故事充满了力量，常有令人惊愕之处，对投资、交易和高风险决策的敏锐洞察比比皆是。通过分享他过往的投资案例，作者详细讲述：为什么正确的榜样是投资成功的关键；如何构建更好的投资流程；如何过滤掉市场中让大多数投资者受干扰的短期噪音，并从中获利。最重要的是，他解释了对自我清楚的认知如何帮助他梳理思绪，并做出更好的投资决策——而不是被好胜心、嫉妒、恐惧所驱动进行决策。书中还介绍了他与著名投资家莫尼什•帕伯莱共同总结的“投资者检查清单”，这样的检查清单可避免投资者犯重大错误。作者还给出了一些投资建议和技巧，以及做出明智决策的方法。\n对于任何对投资感兴趣的人，对于那些想要通过走不同道路获得成功的投资者，本书将提供视野、指导与激励。",
				"libraryCatalog": "Douban2",
				"numPages": "232",
				"publisher": "中国青年出版社",
				"url": "https://book.douban.com/subject/26427201/",
				"attachments": [],
				"tags": [
					{
						"tag": "8⭐"
					}
				],
				"notes": [
					{
						"note": "<h1>#摘录-《与巴菲特共进午餐时,我顿悟到的5个真理》目录</h1>\n\n        前言<br>\n        1 从深入虎穴到沃伦•巴菲特<br>\n        2 精英教育的风险<br>\n        3 火中漫步：我作为价值投资者的第一步<br>\n        4 深陷纽约旋涡<br>\n        5 遇见投资大师莫尼什•帕伯莱<br>\n        6 与巴菲特共进午餐，我顿悟到的5个真理<br>\n        7 真理1 ：坚持自己的原则——带我渡过金融危机<br>\n        8 真理2 ：远离疯狂人群与噪音——创建我自己版本的奥马哈<br>\n        9 真理3 ：永葆童真与好奇心——学跳踢踏舞<br>\n        10 真理4 ：培养并维系有价值的人际关系——像巴菲特、帕伯莱那样投资<br>\n        11 真理5 ：忠实于自己——价值投资探索之旅的终点<br>\n        12 投资的8条规则：构建更好的投资流程<br>\n        13 一位投资者的检查清单：来自一位外科医生的生存策略<br>\n        致谢<br>\n        参考书目及进一步阅读指南<br>\n     "
					},
					{
						"note": "作者简介:\n盖伊•斯皮尔已经运营蓝宝石基金长达18年，取得了令人难忘的成功和震撼市场的回报。作为沃伦•巴菲特的热心门徒，盖伊从1500万美元资金起家，严格复制了巴菲特1950年代的合伙人费率结构与方式。2007年6月，他和投资大师莫尼什•帕伯莱出价65.01万美元，竞拍到与“股神”巴菲特共进慈善午餐的机会。在创立蓝宝石基金之前，他曾在纽约担任投资银行经理，并在伦敦与巴黎短暂从事过企业管理咨询工作。\n斯皮尔还是财经评论员，曾在CNN、CNBC、彭博电视台、福克斯商业新闻等媒体发表评论。\n斯皮尔以名列前茅的成绩获得牛津大学政治哲学经济学位，曾与英国首相卡梅伦共同修经济学课程，之后在哈佛商学院完成MBA学业。\n\n"
					}
				],
				"seeAlso": [],
				"shortTitle": "与巴菲特共进午餐时,我顿悟到的5个真理",
				"extra": "评价人数：605；原作名：《The Education of a Value Investor: My Transformative Quest for Wealth, Wisdom, and Enlightenment》；价：49.00 元;"
			}
		]
	},
	{
		"type": "web",
		"url": "https://book.douban.com/subject/30310664/",
		"items": [
			{
				"itemType": "book",
				"title": "手把手教你买基金",
				"creators": [
					{
						"firstName": "",
						"lastName": "书签客",
						"creatorType": "author",
						"fieldMode": true
					}
				],
				"date": "2018-08-01",
				"ISBN": "9787115488718",
				"libraryCatalog": "Douban2",
				"numPages": "229",
				"publisher": "人民邮电出版社",
				"url": "https://book.douban.com/subject/30310664/",
				"attachments": [],
				"tags": [
					{
						"tag": "8⭐"
					}
				],
				"notes": [],
				"seeAlso": [],
				"extra": "评价人数：400；价：55.00 元;"
			}
		]
	}
]
/** END TEST CASES **/
